// Copyright Epic Games, Inc. All Rights Reserved.

#pragma once

#include "NetworkReplayStreaming.h"
#include "Subsystems/GameInstanceSubsystem.h"
#include "GameplayTagContainer.h"

#include "LyraReplaySubsystem.generated.h"

#define UE_API LYRAGAME_API

class UDemoNetDriver;
class APlayerController;
class ULocalPlayer;
struct FFrame;

/** 用于在UI中显示的可用回放 */
UCLASS(MinimalAPI, BlueprintType)
class ULyraReplayListEntry : public UObject
{
	GENERATED_BODY()

public:
	FNetworkReplayStreamInfo StreamInfo; // 流信息

	/**
	 * 获取流的UI友好名称
	 */
	UFUNCTION(BlueprintPure, Category=Replays)
	FString GetFriendlyName() const { return StreamInfo.FriendlyName; }

	/**
	 * 获取流记录的时间戳
	 */
	UFUNCTION(BlueprintPure, Category=Replays)
	FDateTime GetTimestamp() const { return StreamInfo.Timestamp; }

	/**
	 * 获取流的持续时间（毫秒）
	 */
	UFUNCTION(BlueprintPure, Category=Replays)
	FTimespan GetDuration() const { return FTimespan::FromMilliseconds(StreamInfo.LengthInMS); }

	/**
	 * 获取观看此流的观众数量
	 */
	UFUNCTION(BlueprintPure, Category=Replays)
	int32 GetNumViewers() const { return StreamInfo.NumViewers; }

	/**
	 * 获取流是否为直播状态
	 */
	UFUNCTION(BlueprintPure, Category=Replays)
	bool GetIsLive() const { return StreamInfo.bIsLive; }
};

/** 查询回放的结果列表，用于UI */
UCLASS(MinimalAPI, BlueprintType)
class ULyraReplayList : public UObject
{
	GENERATED_BODY()

public:
	UPROPERTY(BlueprintReadWrite, Category=Replays)
	TArray<TObjectPtr<ULyraReplayListEntry>> Results; // 结果数组
};

/** 处理录制/加载回放的子系统 */
UCLASS(MinimalAPI)
class ULyraReplaySubsystem : public UGameInstanceSubsystem
{
	GENERATED_BODY()

public:
	UE_API ULyraReplaySubsystem();

	/**
	 * 检查平台是否支持回放功能
	 */
	UFUNCTION(BlueprintCallable, Category = Replays, BlueprintPure = false)
	static UE_API bool DoesPlatformSupportReplays();

	/**
	 * 获取平台支持的特性标签，用于选项设置
	 */
	static UE_API FGameplayTag GetPlatformSupportTraitTag();

	/**
	 * 加载适当的地图并播放回放
	 */
	UFUNCTION(BlueprintCallable, Category=Replays)
	UE_API void PlayReplay(ULyraReplayListEntry* Replay);

	/**
	 * 开始录制客户端回放，并处理所需的文件清理
	 */
	UFUNCTION(BlueprintCallable, Category = Replays)
	UE_API void RecordClientReplay(APlayerController* PlayerController);

	/**
	 * 开始删除本地回放，从最旧的开始，直到只剩下NumReplaysToKeep个或更少
	 */
	UFUNCTION(BlueprintCallable, Category = Replays)
	UE_API void CleanupLocalReplays(ULocalPlayer* LocalPlayer, int32 NumReplaysToKeep);

	/**
	 * 在当前播放的回放中前进或后退
	 */
	UFUNCTION(BlueprintCallable, Category=Replays)
	UE_API void SeekInActiveReplay(float TimeInSeconds);

	/**
	 * 获取当前回放的长度
	 */
	UFUNCTION(BlueprintCallable, Category = Replays, BlueprintPure = false)
	UE_API float GetReplayLengthInSeconds() const;

	/**
	 * 获取当前播放时间
	 */
	UFUNCTION(BlueprintCallable, Category=Replays, BlueprintPure=false)
	UE_API float GetReplayCurrentTime() const;

private:
	TSharedPtr<INetworkReplayStreamer> CurrentReplayStreamer; // 当前回放流器

	UPROPERTY()
	TObjectPtr<ULocalPlayer> LocalPlayerDeletingReplays; // 正在删除回放的本地玩家

	int32 DeletingReplaysNumberToKeep; // 删除回放时要保留的数量

	/**
	 * 获取演示网络驱动器
	 */
	UDemoNetDriver* GetDemoDriver() const;

	/**
	 * 当删除操作的枚举流完成时调用
	 */
	void OnEnumerateStreamsCompleteForDelete(const FEnumerateStreamsResult& Result);

	/**
	 * 当删除回放完成时调用
	 */
	void OnDeleteReplay(const FDeleteFinishedStreamResult& DeleteResult);
};

#undef UE_API